/**
 * Copyright (c) [2025] [何屹林]
 *
 * 保留所有权利。
 *
 * 文件名称：LR_1_ProcessShow.h
 * 模块功能说明：
 * 该模块实现逻辑处理类中关于LR1的分析过程相关内容的运算与展示接口
 *
 * 华南师范大学-计算机学院-网络工程-1班
 * 作者：何屹林-20222132023
 * 完成日期：2025年7月24日
 */
#include "logic.h"

QVector<QVector<QString>> Logic::lr1_ProcessShow()
{
    analysisStack.push_back(Lex{"$","0"});
    token_makecd["$"]=0;
    QVector<SyntaxNode*> treeStack;

    int value_id;                   //data
    QString value_inum;             //编号
    QVector<QString> analysisInfo,inputInfo,motionInfo;             //分析消息，输入消息和动作消息，分别展示在三个框中

    QString startInfo=" $[0]";
    for(int i=0;i<Lexs.size();)
    {
        value_id =QString::fromStdString(analysisStack.back().value).toInt();

        value_inum = token_makecd.key(std::stoi(Lexs[i].kind));

        if(i)analysisInfo.push_back(analysisInfo.back());
        else analysisInfo.push_back(startInfo);
        inputInfo.push_back(QString::fromStdString(Lexs[i].kind+"->"+Lexs[i].value));

        LR1TableItem move = LR1Table[value_id][actionList.indexOf(value_inum)];        //动作，kind表示动作类型，idx表示目标在lr1分析表中的位置

        switch (move.kind) {
        case 1:// 移进
        {
            Lex lex = Lexs[i];
            QString currentToken=token_makecd.key(std::stoi(lex.kind));
            QString s = QString::number(move.idx);          //下一个位置

            reduceList_1.push_back(QString::fromStdString(lex.value));
            analysisStack.push_back(Lex{lex.value,s.toStdString()});

            QString temp=QString::fromStdString(lex.value)+"["+s+"]";
            analysisInfo.back()+=' '+temp;
            motionInfo.push_back("移进，使用表中状态"+QString::number(move.idx));

            SyntaxNode *newNode = new SyntaxNode(currentToken);
            treeStack.push_back(newNode);

            i++;
            break;
        }
        case 2:  // 归约
        {
            for(int j=0;j<Grams[move.idx].r.size();j++){
                analysisInfo.back().resize(analysisInfo.back().lastIndexOf(' '));
            }

            QString t=Grams[move.idx].l;

            QString temp;
            for(auto s:Grams[move.idx].r)
                temp+=s;

            SyntaxNode *parNode = new SyntaxNode(t); // 创建规约后的父节点
            QVector<SyntaxNode*> childNodes; // 用于存储规约的子节点

            // 从栈中移除规约符号
            for (int i = 0; i < Grams[move.idx].r.size(); i++) {
                childNodes.push_back(treeStack.back()); // 将子节点添加到父节点
                treeStack.pop_back();
            }
            std::reverse(childNodes.begin(), childNodes.end()); // 规约后子节点顺序需要反转
            parNode->children = childNodes;
            treeStack.push_back(parNode);// 将子节点添加到父节点

            motionInfo.push_back("归约，使用文法"+t+"->"+temp);

            analysisStack.erase(analysisStack.end() - Grams[move.idx].r.size(), analysisStack.end());

            value_id = QString::fromStdString(analysisStack.back().value).toInt();//上一个的序号
            move = LR1Table[value_id][actionList.indexOf(Grams[move.idx].l)];

            analysisStack.push_back(Lex{ t.toStdString(), move.toStr().toStdString() });  // 跳转至新状态;

            t+="["+QString::number(move.idx)+"]";
            analysisInfo.back()+=' '+t;

            break;
        }
        case 3:  //非终结符移进,正常来说不会运行
        {
            ::exit(0);
            break;
        }
        case 4:  // 接受
        {
            ++i;
            ROOT=treeStack.back();

            for(int j=0;j<Grams[move.idx].r.size();j++){
                analysisInfo.back().resize(analysisInfo.back().lastIndexOf(' '));
            }
            QString t=Grams[move.idx].l;

            QString temp;
            for(auto s:Grams[move.idx].r)
                temp+=s;

            motionInfo.push_back("最终接受，使用文法"+Grams[move.idx].l+"->"+temp);

            analysisStack.erase(analysisStack.end() - Grams[move.idx].r.size(), analysisStack.end());

            value_id = stoi(analysisStack.back().value);//上一个的序号
            move = LR1Table[value_id][actionList.indexOf(Grams[move.idx].l)];

            analysisStack.push_back(Lex{ t.toStdString(), move.toStr().toStdString() });  // 跳转至新状态;

         break;
        }
        default://正常不应该出现
        {
         qDebug() << "未知动作: " << move.kind<<' '<<move.idx << '\n';
         motionInfo.push_back("错误");
         i=Lexs.size();
    }
        }
    }

    //以上生成对应的LR1分析过程

    QVector<QVector<QString>> contentTable(analysisInfo.size(),QVector<QString>(3));

    for(int i=0;i<analysisInfo.size();i++)
    {
        if(!analysisInfo[i].isEmpty())
                contentTable[i][0]=analysisInfo[i];
        if(!inputInfo[i].isEmpty())
                contentTable[i][1]=inputInfo[i];
        if(!motionInfo[i].isEmpty())
                contentTable[i][2]=motionInfo[i];
    }

    return contentTable;
}
